package com.shrct.businessprocess.product.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.product.RCAnonymousProductEntry;
import com.shrct.businessprocess.product.RCAnonymouseProductEntryRoot;
import com.shrct.businessprocess.product.RCAnonymouseProductEntryRootStatus;
import com.shrct.businessprocess.product.RCProductSpecification;
import com.shrct.businessprocess.product.impl.RCAnonymousProductEntryImpl;
import com.shrct.businessprocess.product.proxy.RCAnonymouseProductEntryRootProxy;
import com.shrct.businessprocess.purchase.RCPurchaseOrderItem;
import com.uniquesoft.uidl.validation.Validates;
import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("RCANONYMOUSEPRODUCTENTRYROOT_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcanonymouseproductentryroot")
public class RCAnonymouseProductEntryRootImpl extends BaseModelObject implements RCAnonymouseProductEntryRoot {
  public RCAnonymouseProductEntryRootImpl() {
    super();
  }
  
  private RCAnonymouseProductEntryRootStatus Status;
  
  public RCAnonymouseProductEntryRootStatus getStatus() {
    return this.Status;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start() {
    
    Status=RCAnonymouseProductEntryRootStatus.existing;
  }
  
  public void start() {
    if(Status==null){
    	_start();
    	getModelObjectLogService().createLog(this,"Status","Start");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCAnonymouseProductEntryRootEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private void __inStock(final RCPurchaseOrderItem orderItem, final Integer quantity) {
    
    boolean _greaterEqualsThan = ((quantity).intValue() >= 0);
    Validates.Assert(_greaterEqualsThan, "\u5165\u5E93\u6570\u91CF\u4E0D\u80FD\u5C0F\u4E8E0");
    RCProductSpecification _productSpec = orderItem.getProductSpec();
    RCAnonymousProductEntry _hostEntry = this.getHostEntry();
    RCProductSpecification _type = _hostEntry.getType();
    boolean _equals = Objects.equal(_productSpec, _type);
    Validates.Assert(_equals, "\u5165\u5E93\u7C7B\u578B\u4E0D\u5339\u914D");
  }
  
  public void _inStock(final RCPurchaseOrderItem orderItem, final Integer quantity) {
    if(Status==RCAnonymouseProductEntryRootStatus.existing){
    	__inStock(orderItem,quantity);
    	getModelObjectLogService().createLog(this,"Status","_inStock");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCAnonymouseProductEntryRootEventsManager.class).fire_inStock(this,orderItem,quantity);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void __deliver(final RCAnonymousProductEntry target, final Integer quantity) {
    
    final Function1<RCAnonymousProductEntry,Boolean> _function = new Function1<RCAnonymousProductEntry,Boolean>() {
        public Boolean apply(final RCAnonymousProductEntry it) {
          Integer _count = it.getCount();
          boolean _greaterEqualsThan = ((_count).intValue() >= 0);
          return Boolean.valueOf(_greaterEqualsThan);
        }
      };
    boolean _forall = IterableExtensions.<RCAnonymousProductEntry>forall(this.entries, _function);
    Validates.Assert(_forall, "\u5E93\u5B58\u6570\u91CF\u4E0D\u80FD\u5C0F\u4E8E0");
    RCProductSpecification _type = target.getType();
    RCAnonymousProductEntry _hostEntry = this.getHostEntry();
    RCProductSpecification _type_1 = _hostEntry.getType();
    boolean _equals = Objects.equal(_type, _type_1);
    Validates.Assert(_equals, "\u53D1\u8D27\u7C7B\u578B\u4E0D\u5339\u914D");
  }
  
  public void _deliver(final RCAnonymousProductEntry target, final Integer quantity) {
    if(Status==RCAnonymouseProductEntryRootStatus.existing){
    	__deliver(target,quantity);
    	getModelObjectLogService().createLog(this,"Status","_deliver");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCAnonymouseProductEntryRootEventsManager.class).fire_deliver(this,target,quantity);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void __return(final RCAnonymousProductEntry source, final Integer quantity) {
    
    final Function1<RCAnonymousProductEntry,Boolean> _function = new Function1<RCAnonymousProductEntry,Boolean>() {
        public Boolean apply(final RCAnonymousProductEntry it) {
          Integer _count = it.getCount();
          boolean _greaterEqualsThan = ((_count).intValue() >= 0);
          return Boolean.valueOf(_greaterEqualsThan);
        }
      };
    boolean _forall = IterableExtensions.<RCAnonymousProductEntry>forall(this.entries, _function);
    Validates.Assert(_forall, "\u5E93\u5B58\u6570\u91CF\u4E0D\u80FD\u5C0F\u4E8E0");
    RCProductSpecification _type = source.getType();
    RCAnonymousProductEntry _hostEntry = this.getHostEntry();
    RCProductSpecification _type_1 = _hostEntry.getType();
    boolean _equals = Objects.equal(_type, _type_1);
    Validates.Assert(_equals, "\u9000\u8D27\u7C7B\u578B\u4E0D\u5339\u914D");
  }
  
  public void _return(final RCAnonymousProductEntry source, final Integer quantity) {
    if(Status==RCAnonymouseProductEntryRootStatus.existing){
    	__return(source,quantity);
    	getModelObjectLogService().createLog(this,"Status","_return");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCAnonymouseProductEntryRootEventsManager.class).fire_return(this,source,quantity);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  public Boolean isExisting() {
    return com.shrct.businessprocess.product.RCAnonymouseProductEntryRootStatus.existing==Status;
  }
  
  private String batchSid;
  
  public String getBatchSid() {
    return this.batchSid;
  }
  
  public RCAnonymouseProductEntryRoot setBatchSid(final String batchSid) {
    this.batchSid = batchSid;
    return this;			
    
  }
  
  @OneToMany(targetEntity = RCAnonymousProductEntryImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "entryRoot")
  private Collection<RCAnonymousProductEntry> entries = new java.util.ArrayList<com.shrct.businessprocess.product.RCAnonymousProductEntry>();;
  
  public Collection<RCAnonymousProductEntry> getEntries() {
    return this.entries;
  }
  
  public RCAnonymousProductEntry createAndAddtoEntries() {
    getEntries().size();
    com.shrct.businessprocess.product.RCAnonymousProductEntry rCAnonymousProductEntry = new com.shrct.businessprocess.product.impl.RCAnonymousProductEntryImpl(this);
    getObjectFactory().create(rCAnonymousProductEntry);
    getEntries().add(rCAnonymousProductEntry);
    return rCAnonymousProductEntry;
    
  }
  
  public RCAnonymousProductEntry createAndAddtoEntries(final Procedure1<RCAnonymousProductEntry> updater) {
    getEntries().size();
    com.shrct.businessprocess.product.RCAnonymousProductEntry rCAnonymousProductEntry = new com.shrct.businessprocess.product.impl.RCAnonymousProductEntryImpl(this);
    getObjectFactory().create(rCAnonymousProductEntry);
    getEntries().add(rCAnonymousProductEntry);
    return rCAnonymousProductEntry;
    
  }
  
  public RCAnonymouseProductEntryRoot removeAllEntries() {
    for(RCAnonymousProductEntry obj : this.entries){
    	getObjectFactory().delete(obj);
    }
    this.entries.clear();
    return this;	
    
  }
  
  public RCAnonymouseProductEntryRoot removeFromEntries(final RCAnonymousProductEntry rCAnonymousProductEntry) {
    this.entries.remove(rCAnonymousProductEntry);
    getObjectFactory().delete(rCAnonymousProductEntry);
    return this;
    
  }
  
  public RCAnonymousProductEntry getHostEntry() {
    RCAnonymousProductEntry _head = IterableExtensions.<RCAnonymousProductEntry>head(this.entries);
    return _head;
  }
  
  public static RCAnonymouseProductEntryRoot create(final IObjectFactory objectFactory) {
    com.shrct.businessprocess.product.RCAnonymouseProductEntryRoot rCAnonymouseProductEntryRoot = new com.shrct.businessprocess.product.impl.RCAnonymouseProductEntryRootImpl(
    );
    objectFactory.create(rCAnonymouseProductEntryRoot);
    return rCAnonymouseProductEntryRoot;			
    
  }
  
  public static RCAnonymouseProductEntryRoot createRCAnonymouseProductEntryRootImpl(final IObjectFactory objectFactory, final Procedure1<RCAnonymouseProductEntryRoot> init) {
    com.shrct.businessprocess.product.RCAnonymouseProductEntryRoot rCAnonymouseProductEntryRoot = new com.shrct.businessprocess.product.impl.RCAnonymouseProductEntryRootImpl(
    );
    objectFactory.create(rCAnonymouseProductEntryRoot);
    init.apply(rCAnonymouseProductEntryRoot);
    
    return rCAnonymouseProductEntryRoot;			
    
  }
  
  public RCAnonymouseProductEntryRootProxy toProxy() {
    com.shrct.businessprocess.product.proxy.RCAnonymouseProductEntryRootProxy proxy = new com.shrct.businessprocess.product.proxy.RCAnonymouseProductEntryRootProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setStatus(this.getStatus().name());
    return proxy;
    
  }
}
